home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1997 September
/
Macworld (1997-09).dmg
/
Shareware World
/
Utilities
/
Text Processing
/
Alpha
/
Tcl
/
SystemCode
/
DblClickAux.tcl
< prev
next >
Wrap
Text File
|
1996-08-15
|
13KB
|
399 lines
#############################################################################
# File: DblClickAux.tcl
#
# General utility procs (originally for TeX, BibTeX and Perl modes)
#
# Authors: Tom Pollard <pollard@chem.columbia.edu>
# Tom Scavo <trscavo@syr.edu>
#
#############################################################################
#############################################################################
# Take any valid Macintosh filespec as input, and return the
# corresponding absolute filespec. Filenames without an explicit
# folder are resolved relative to the folder of the current document.
#
proc absolutePath {filename} {
set name [file tail $filename]
set subdir [file dirname $filename]
if { [string length $subdir] > 0 && [string index $subdir 0] != ":" } {
set dir ""
} else {
set dir [file dirname [lindex [winNames -f] 0]]
}
return "$dir$subdir:$name"
}
#############################################################################
# Open the file specified by the full pathname "$filename"
# If it's already open, just switch to it without any fuss.
#
proc openFileQuietly {filename} {
if {[lsearch [winNames -f] $filename] >= 0} {
bringToFront $filename
} elseif {[file exists $filename]} {
edit -w $filename
} else {
error "Couldn''t find \"$filename\""
}
}
#############################################################################
# Searches $filename for the given pattern $searchString. If the
# search is successful, returns the matched string; otherwise returns
# the empty string. If the flag 'indices' is true and the search is
# successful, returns a list of two pos giving the indices of the
# found string; otherwise returns the list '-1 -1'.
#
proc searchInFile {filename searchString {indices 0}} {
# Get the text of the file to be searched:
if {[lsearch [winNames -f] $filename] >= 0} {
set fileText [getText -w $filename 0 [maxPos -w $filename]]
} elseif {[file exists $filename]} {
set fd [open $filename]
set fileText [read $fd]
close $fd
} else {
if { $indices } {
return [list -1 -1]
} else {
return ""
}
}
# Search the text for the search string:
if { $indices } {
if {[regexp -indices $searchString $fileText mtch]} {
# Fixes an apparent bug in 'regexp':
return [list [lindex $mtch 0] [expr [lindex $mtch 1] + 1]]
} else {
return [list -1 -1]
}
} else {
if {[regexp $searchString $fileText mtch]} {
return $mtch
} else {
return ""
}
}
}
#############################################################################
# Read and return the complete contents of the specified file.
#
proc readFile {fileName} {
if {[file exists $fileName] && [file readable $fileName]} {
set fileid [open $fileName "r"]
set contents [read $fileid]
close $fileid
return $contents
} else {
error "No readable file found"
}
}
#############################################################################
# Save $text in $filename. If $text is null, create an empty file.
# Overwrite if $overwrite is true or the file does not exist;
# otherwise, prompt the user.
#
proc writeFile {filename {text {}} {overwrite 0}} {
if { $overwrite || ![file exists $filename] } {
message "Saving $filename…"
set fd [open $filename "w"]
puts $fd $text
close $fd
} else {
switch [askyesno "File $filename exists! Overwrite?"] {
"yes" {
writeFile $filename $text 1
}
"no" {
message "No file written"
}
}
}
}
#############################################################################
# Highlight (select) a particular line in the designated file, opening the
# file if necessary. Returns the full name of the buffer containing the
# opened file. If provided, a message is displayed on the status line.
#
proc gotoFileLine {fname line {mesg {}}} {
if {[expr {[lsearch [winNames -f] "*$fname"] >= 0}]} {
bringToFront $fname
} elseif {[expr {[lsearch [winNames] "*$fname"] >= 0}]} {
bringToFront $fname
} elseif {[file exists $fname]} {
edit $fname
catch {shrinkWindow 2}
} else {
alertnote "File \" $fname \" not found."
return
}
set pos [rowColToPos $line 0]
select [lineStart $pos] [nextLineStart $pos]
if {[string length $mesg]} { message $mesg }
return [lindex [winNames -f] 0]
}
###########################################################################
# Parse a string into "word"s, which include blocks of non-space text,
# double- and single-quoted strings, and blocks of text enclosed in
# balanced parentheses or curly brackets.
#
# If a word is delimited by a quote or paren character (\", \', \(, or \{),
# then _that_ particular delimiter may be included within the word if it is
# backslash-quoted, as above. No other characters are special or need quoting
# with that word. The quoted delimiters are unquoted in the list of words
# returned.
#
proc parseWords {entry} {
set slash "\\"
set qslash "\\\\"
set words {}
set entry [string trim $entry]
while {[string length $entry]} {
set delim [string range $entry 0 0]
set entry [string range $entry 1 end]
# regexp $endPat matches the end of the word
# $openPat matches the open delimiter
# $unescPat matches escaped instances of the open/close delimiters
#
# $type == "quote" means open/close delimiters are the same
# == "paren" means there's a close delimiter and nesting is possible
# == "unquoted" means the word is delimited by whitespace.
#
if {$delim == {"}} { set endPat {^([^"]*)"}
set unescPat {\\(")}
set type quote
} elseif {$delim == {'}} { set endPat {^([^']*)'}
set unescPat {\\(')}
set type quote
} elseif {$delim == "\{"} { set endPat "^(\[^\}\]*)\}"
set openPat "\{"
set unescPat "\\\\(\[\{\}\])"
set type paren
} elseif {$delim == "("} { set endPat {^([^)]*)\)}
set openPat {(}
set unescPat {\\([()])}
set type paren
} else { set type unquoted
}
if {$type == "quote"} {
set ck $qslash
set fld ""
while {$ck == $qslash} {
set ok [regexp -indices $endPat $entry mtch sub1]
if {$ok} {
append fld [string range $entry [lindex $mtch 0] [lindex $mtch 1]]
set ck $slash[string range $entry [lindex $sub1 1] [lindex $sub1 1]]
set pos [expr 1 + [lindex $mtch 1]]
set entry [string range $entry $pos end]
} else {
error "Couldn't match $delim as field delimiter"
}
}
set pos [expr [string length $fld] - 2]
set fld [string range $fld 0 $pos]
regsub -all $unescPat $fld {\1} fld
} elseif {$type == "paren"} {
set nopen 1
set nclose 0
set fld ""
while {$nopen - $nclose != 0} {
set ok [regexp -indices $endPat $entry mtch sub1]
if {$ok} {
append fld [string range $entry [lindex $mtch 0] [lindex $mtch 1]]
set ck $slash[string range $entry [lindex $sub1 1] [lindex $sub1 1]]
set entry [string range $entry [expr 1 + [lindex $mtch 1]] end]
regsub -all $unescPat $fld {} fld1
set nopen [llength [split $fld1 $openPat]]
if {$ck != $qslash} { incr nclose }
} else {
error "Couldn't match $delim as field delimiter"
}
}
set pos [expr [string length $fld] - 2]
set fld [string range $fld 0 $pos]
regsub -all $unescPat $fld {\1} fld
} elseif {$type == "unquoted"} {
set entry ${delim}${entry}
set ok [regexp -indices {^([^ ]*)} $entry mtch sub1]
if {$ok} {
set fld [string range $entry [lindex $sub1 0] [lindex $sub1 1]]
set pos [expr 1 + [lindex $mtch 1]]
set entry [string range $entry $pos end]
} else {
set fld ""
set entry ""
}
} else {
error "parseWords: unrecognized case"
}
lappend words $fld
set entry [string trimleft $entry]
}
return $words
}
##
# -------------------------------------------------------------------------
#
# "buildSubMenu" --
#
# Given a list of folders, 'buildSubMenu' returns a hierarchical menu based
# on the files and subfolders in each of these folders. Pathnames are
# optionally stored in a global array given by the argument 'filePaths'.
# The path's index in this array is formed by concatenating the submenu
# name and the filename, allowing the pathname to be retrieved by the
# procedure 'proc' when the menu item is selected.
#
# The search may be restricted to files with specific extensions, or files
# matching a certain pattern. A search depth may also be given, with three
# levels of subfolders assumed by default.
#
# See MacPerl.tcl or latexMenu.tcl for examples.
#
# (originally written by Tom Pollard, with modifications by Vince Darley
# and Tom Scavo)
#
# --Version--Author------------------Changes-------------------------------
# 1.0 Tom Pollard original
# 2.0 <vince@das.harvard.edu> multiple extensions, optional paths
# 2.1 Tom Scavo multiple folders
# 2.2 <vince@das.harvard.edu> pattern matching as well as exts
# 2.3 <vince@das.harvard.edu> handles unique menu-names and does text only
# -------------------------------------------------------------------------
##
proc buildSubMenu {folders name proc {filePaths ""} {exts ""} {depth 3} {fset ""}} {
global filesetFlags
if { $filePaths != "" } {
global $filePaths
}
incr depth -1
set overallMenu {}
foreach folder $folders {
if {[file exists $folder]} {
if {![file isdirectory $folder]} {
set folder "[file dirname $folder]:"
}
if {[string length [file tail $folder]] > 0} {
set folder "$folder:"
}
if {$name == 0} {
set name [file tail [file dirname $folder]]
}
# if it's a fileset, we register _before_ recursing
if { $fset != "" } {
set mname [registerFilesetMenuName $fset $name $proc]
} else {
set mname $name
}
set menu {}
if $filesetFlags(includeNonTextFiles) {
set filenames [glob -nocomplain ${folder}*]
} else {
set filenames [lsort -ignore [concat [glob -nocomplain ${folder}*:] \
[glob -nocomplain -t TEXT ${folder}*]]]
}
if {[llength $filenames] > 0} {
foreach m $filenames {
if {[file isdirectory $m] && $depth > 0} {
set subM [buildSubMenu [list ${m}] 0 $proc $filePaths $exts $depth $fset]
if { $subM != "" } { lappend menu $subM }
} elseif {[file isfile $m]} {
set fname [file tail $m]
if { $exts == "" || [lsearch ${exts} [file extension $fname] ] != -1 \
|| [string match $exts $fname] } {
lappend menu $fname
if { $filePaths != "" } {
set ${filePaths}($name:$fname) $m
}
}
}
}
}
if { $menu != "" } {
set overallMenu [concat $overallMenu $menu]
}
} else {
beep
alertnote "buildSubMenu: Folder $folder does not exist!"
}
}
if { $overallMenu != "" } {
if { [string length $proc] > 1 } {
set pproc "-p $proc"
} else {
set pproc ""
}
if { $fset != "" } {
if { [string length $proc] > 1 } { set pproc "-p subMenuProc" }
}
return [concat {menu -m -n} [list $mname] $pproc [list $overallMenu]]
} else {
return ""
}
}
# in case we've done something odd elsewhere
if ![info exists filesetFlags(includeNonTextFiles)] {
set filesetFlags(includeNonTextFiles) 0
}
#############################################################################
# Return a list of all subfolders found within $folder,
# down to some maximum recursion depth. The top-level
# folder is not included in the returned list.
#
proc listSubfolders {folder {depth 3}} {
set folders {}
if {$depth > 0} {
incr depth -1
if {[string length [file tail $folder]] > 0} {
set folder "$folder:"
}
foreach m [glob -nocomplain $folder\*] {
if {[file isdirectory $m]} {
set folders [concat $folders [list $m]]
set folders [concat $folders [listSubfolders ${m}: $depth]]
}
}
}
return $folders
}
#############################################################################
proc commandClick {from to url} {
select $from
for {set i 0} {$i < 200} {incr i} {}
select $from $to
for {set i 0} {$i < 200} {incr i} {}
select $from
for {set i 0} {$i < 200} {incr i} {}
select $from $to
icURL $url
}